package com.exam.service.impl;

import com.exam.pojo.base.PageResult;
import com.exam.pojo.domain.Question;
import com.exam.pojo.domain.User;
import com.exam.pojo.dto.AnswerDTO;
import com.exam.pojo.dto.QuestionDTO;
import com.exam.service.IQuestionService;
import com.exam.utils.CollUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : LG
 */
@Service
@RequiredArgsConstructor
public class QuestionServiceImpl implements IQuestionService {

    private final MongoTemplate mongoTemplate;

    @Override
    public PageResult<Question> list(QuestionDTO dto) {
        Integer type = dto.getType();
        switch (type){
            case 1:
                //查询所有题目
                return findAll();
            case 2:
                //随机练习(排除用户已经做过的题目
                return findRandomList(dto.getUuid(),dto.getSize());
            case 3:
                //错题库
                return findErrorOrCollectList(dto.getUuid(),dto.getPage(),dto.getSize(),1);
            case 4:
                //收藏题库
                return findErrorOrCollectList(dto.getUuid(),dto.getPage(),dto.getSize(),2);
            case 5:
                //图标题库
                return findHasImagList(dto.getUuid(),dto.getPage(),dto.getSize());
            case 6:
                //分类题目库
                return findCateList(dto.getUuid(),dto.getPage(),dto.getSize(),dto.getCateId());
            case 7:
                //易错题
                return findEasyErrList(dto.getSize());
            case 8:
                //未做题目
                return findUnFinishList(dto.getUuid(),dto.getPage(),dto.getSize());
            default:
                return PageResult.empty();
        }
    }

    @Override
    public void submit(AnswerDTO dto) {

        //1.修改题目的回答次数和错误次数
        Update update = new Update().inc("answerNum",1);
        if(!dto.getCorrect()){
            update.inc("errNum",1);
        }
        mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(dto.getQuestionId())),
                    update,
                    Question.class
                );
        //2.修改用户信息
        Update userUpdate = new Update().inc("answerNums",1)
                .addToSet("finishQuestionIds",dto.getQuestionId());
        if(dto.getCorrect()){
            userUpdate.inc("correctNums",1);
        }else{
            userUpdate.inc("errorNums",1);
            userUpdate.addToSet("errorQuestionIds",dto.getQuestionId());
        }
        mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(dto.getUuid())),
                userUpdate,
                User.class);
    }

    @Override
    public List<String> queryEasyerrList() {
        Query query = new Query();
        query.with(Sort.by(Sort.Order.desc("errNum")));
        query.limit(100);
        List<Question> questions = mongoTemplate.find(query, Question.class);
        if(CollUtils.isNotEmpty(questions)){
            List<Long> ids = CollUtils.getFieldValues(questions, "id", Long.class);
            return ids.stream().map(id->id.toString()).collect(Collectors.toList());
        }
        return CollUtils.emptyList();
    }

    @Override
    public Question getById(Long id) {
        return mongoTemplate.findById(id,Question.class);
    }

    @Override
    public void updateQuestion(Question question) {
        mongoTemplate.save(question);
    }

    /**
     * 查询所有题目
     */
    private PageResult<Question> findAll(){
        List<Question> list = mongoTemplate.findAll(Question.class);
        return PageResult.of(list.size(),list);
    }

    /**
     * 随机练习
     */
    private PageResult<Question> findRandomList(String uuid, Integer size){
        //查询用户列表
        User user = mongoTemplate.findById(uuid, User.class);
        if(user!=null){
            //已经做过的题目列表
            List<Long> finishQuestionIds = user.getFinishQuestionIds();
            Criteria criteria = new Criteria();
            if(CollUtils.isNotEmpty(finishQuestionIds)){
                criteria.and("id").nin(finishQuestionIds);
            }
            //题目分类
            List<Long> categoryIds = user.getCategoryIds();
            if(CollUtils.isNotEmpty(categoryIds) && categoryIds.size()!=9){
                criteria.and("cateId").in(categoryIds);
            }
            Aggregation aggregate = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.sample(size)
            );
            AggregationResults<Question> result = mongoTemplate.aggregate(aggregate, Question.class, Question.class);
            List<Question> list = result.getMappedResults();
            return PageResult.of(size,list);
        }else{
            AggregationResults<Question> result = mongoTemplate.aggregate(Aggregation.newAggregation(
                    Aggregation.sample(size)
            ), Question.class, Question.class);
            List<Question> list = result.getMappedResults();
            return PageResult.of(size,list);
        }
    }
    public PageResult<Question> findErrorOrCollectList(String uuid,Integer page,Integer size,Integer type){
        User user = mongoTemplate.findById(uuid, User.class);
        if(user!=null){
            //1. 错误列表 2.收藏列表
            List<Long> questionIds = type == 1 ? user.getErrorQuestionIds() : user.getCollectQuestionIds();
            if(CollUtils.isNotEmpty(questionIds)){
                Query query = Query.query(Criteria.where("id").in(questionIds));
                List<Question> list = mongoTemplate.find(query.skip((page - 1) * size)
                        .limit(size), Question.class);
                long total = mongoTemplate.count(query, Question.class);
                return PageResult.of(total,list);
            }
        }
        return PageResult.empty();
    }

    public PageResult<Question> findHasImagList(String uuid,Integer page, Integer size){

        Query query = new Query();
        //查询用户列表
        User user = mongoTemplate.findById(uuid, User.class);
        if(user!=null){
            //已经做过的题目列表
            List<Long> finishQuestionIds = user.getFinishQuestionIds();
            if(CollUtils.isNotEmpty(finishQuestionIds)){
                Criteria criteria = Criteria.where("id").nin(finishQuestionIds);
                query.addCriteria(criteria);
            }
        }
        query.addCriteria(Criteria.where("hasImg").is(true));
        List<Question> list = mongoTemplate.find(query.skip((page - 1) * size).limit(size), Question.class);
        long total = mongoTemplate.count(query, Question.class);
        return PageResult.of(total,list);
    }

    public PageResult<Question> findCateList(String uuid,Integer page, Integer size,Long cateId){

        Query query = new Query();
        //查询用户列表
        User user = mongoTemplate.findById(uuid, User.class);
        if(user!=null){
            //已经做过的题目列表
            List<Long> finishQuestionIds = user.getFinishQuestionIds();
            if(CollUtils.isNotEmpty(finishQuestionIds)){
                Criteria criteria = Criteria.where("id").nin(finishQuestionIds);
                query.addCriteria(criteria);
            }
        }
        query.addCriteria(Criteria.where("cateId").is(cateId));
        List<Question> list = mongoTemplate.find(query.skip((page - 1) * size).limit(size), Question.class);
        long total = mongoTemplate.count(query, Question.class);
        return PageResult.of(total,list);
    }
    public PageResult<Question> findEasyErrList(Integer size){
        List<Question> list = mongoTemplate.find(new Query().with(Sort.by(Sort.Direction.DESC, "errNum")).limit(size), Question.class);
        return PageResult.of(Long.valueOf(size),list);
    }
    public  PageResult<Question> findUnFinishList(String uuid,Integer page,Integer size){

        Query query = new Query();
        //查询用户列表
        User user = mongoTemplate.findById(uuid, User.class);
        if(user!=null){
            //已经做过的题目列表
            List<Long> finishQuestionIds = user.getFinishQuestionIds();
            if(CollUtils.isNotEmpty(finishQuestionIds)){
                Criteria criteria = Criteria.where("id").nin(finishQuestionIds);
                query.addCriteria(criteria);
            }
        }
        List<Question> list = mongoTemplate.find(query.skip((page - 1) * size).limit(size), Question.class);
        long total = mongoTemplate.count(query, Question.class);
        return PageResult.of(total,list);
    }
}
